使用者主要是透過 Touch 來跟 Mobile App 互動,跟網頁中的 Click 不太一樣。而它又可以結合各種的手勢,長按一個按鈕、滾動 List、放大縮小地圖、Swipe 等等,這邊會簡單介紹到一些相關的 Component。
React Native 內建許多能處理 Touch 的 Component (統稱 Touchables*),它們都能指定 onPress、onPressIn、onPressOut、onLongPress 等等的 Event Handler,而它們之間的差別在於它們被 Touch 之後會有不同的回饋 (Feedback):
TouchableNativeFeedback 只有 Android 能用,而官方也不建議使用 TouchableWithoutFeedback (完全沒有回饋),所以這兩個就先不介紹了。
TouchableHighlight 在被 Touch 之後會有一個 Highlight 的效果,而 Highlight 的顏色可以透過 underlayColor 改變。
<TouchableHighlight
  onPress={() => {}}
  underlayColor="red"
>
  <View style={styles.btn}>
    <Text style={styles.text}>按鈕</Text>
  </View>
</TouchableHighlight>

更詳細的內容請參閱 TouchableHighlight 的官方文件。
TouchableOpacity 在被 Touch 之後會有一個透明度改變的效果。
<TouchableOpacity
  onPress={() => {}}
>
  <View style={styles.btn}>
    <Text style={styles.text}>按鈕</Text>
  </View>
</TouchableOpacity>

更詳細的內容請參閱 TouchableOpacity 的官方文件。
Button 是在v0.37.0 才導入的新 Component,React Naitve 部落格的這篇文章:Introducing Button, Faster Installs with Yarn, and a Public Roadmap 有介紹了它的由來,以往要做出一個跨平台可用的按鈕不夠簡單,而這是 React Native 未來的方向之一,所以才有了它。
<Button
  onPress={() => {}}
  title="按我啊"
  accessibilityLabel="按我啊"
  color="red"
  disabled={false}
/>

為了簡單明瞭、立即可用,Button 的 API 做出了一些取捨:
onPress,沒有 onPressIn、onLongPress 等等的其他 Handlercolor (在 iOS 是文字顏色、在 Android 是背景顏色) 的客製化,無法設定其他 style
更詳細的內容請參閱 Button 的官方文件。
內容超出一個畫面所能顯示的量時,我們通常需要使用 ScrollView,讓它能藉由往下滑來瀏覽:
<ScrollView>
  <Text style={{ fontSize: 60 }}>帶給各位滿滿的大平台!</Text>
  <Text style={{ fontSize: 60, color: 'red' }}>帶給各位滿滿的大平台!</Text>
  <Text style={{ fontSize: 60, color: 'blue' }}>帶給各位滿滿的大平台!</Text>
  <Text style={{ fontSize: 60 }}>帶給各位滿滿的大平台!</Text>
  <Text style={{ fontSize: 60, color: 'red' }}>帶給各位滿滿的大平台!</Text>
  <Text style={{ fontSize: 60, color: 'blue' }}>帶給各位滿滿的大平台!</Text>
</ScrollView>

在滑動時,右側會出現滾動軸。(GIF 簡化不少影格,所以會比較不順)
更詳細的內容請參閱 ScrollView 的官方文件。
ListView 通常被用在呈現大量陣列資料時使用,不會一次 Render 所有的 Item,只會 Render 呈現在畫面上的 Item,可以改善單純使用 ScrollView 的效能問題。需要傳遞一個 Function 給 renderRow,讓 ListView 知道怎麼去 Render 每一列。
ListView 的 dataSource Prop 接一個 ListView.DataSource,而產生它的時候要給一個回傳 Boolean 值的 rowHasChanged Function,讓它可以判斷兩個 Row 是不是一樣的:
class ListViewBasics extends Component {
  // Initialize the hardcoded data
  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2,
    });
    this.state = {
      dataSource: ds.cloneWithRows([
        '帶給各位!',
        '滿滿的!',
        '大平台!',
        '帶給各位!',
        '滿滿的!',
        '大平台!',
        '帶給各位!',
        '滿滿的!',
        '大平台!',
        '帶給各位!',
        '滿滿的!',
        '大平台!',
      ])
    };
  }
  render() {
    return (
      <View style={{ flex: 1, paddingTop: 22 }}>
        <ListView
          dataSource={this.state.dataSource}
          renderRow={(rowData) => <Text style={{ fontSize: 60 }}>{rowData}</Text>}
        />
      </View>
    );
  }
}

更詳細的內容請參閱 ListView 的官方文件。
這些互動相關的 Component 通常是使用者體驗是否良好的關鍵,在使用時也必須特別小心。